`include "defines.v"

module mem_reg(

    input  wire                clk,
    input  wire                rst,
    input  wire                mem_stall_i,      //~mem_ready

    input  wire [`RAM_BUS]     mem_pc_i,
    input  wire [31:0]         mem_inst_i,
    input  wire                mem_rd_w_ena_i,
    input  wire [`REG_BUS]     mem_rd_w_addr_i,
    input  wire [`REG_WIDTH]   mem_rd_w_data_i,
    input  wire                mem_halt_ena_i,
    input  wire                mem_skip_i,

    input  wire                mem_reg_valid_i,

    input  wire [`REG_WIDTH]   mem_mstatus_i,
    input  wire [`REG_WIDTH]   mem_mie_i,
    input  wire [`REG_WIDTH]   mem_mtvec_i,
    input  wire [`REG_WIDTH]   mem_mepc_i,
    input  wire [`REG_WIDTH]   mem_mcause_i,
    input  wire [`REG_WIDTH]   mem_mtval_i,
    input  wire [`REG_WIDTH]   mem_mip_i,
    input  wire [`REG_WIDTH]   mem_medeleg_i,
    input  wire [`REG_WIDTH]   mem_mideleg_i,
    input  wire [`REG_WIDTH]   mem_mscratch_i,

    output reg  [`RAM_BUS]     mem_pc_o,
    output reg  [31:0]         mem_inst_o,
    output reg                 mem_rd_w_ena_o,
    output reg  [`REG_BUS]     mem_rd_w_addr_o,
    output reg  [`REG_WIDTH]   mem_rd_w_data_o,
    output reg                 mem_halt_ena_o,
    output reg                 mem_skip_o,
    
    output reg                 mem_reg_valid_o,

    output reg  [`REG_WIDTH]   mem_mstatus_o,
    output reg  [`REG_WIDTH]   mem_mie_o,
    output reg  [`REG_WIDTH]   mem_mtvec_o,
    output reg  [`REG_WIDTH]   mem_mepc_o,
    output reg  [`REG_WIDTH]   mem_mcause_o,
    output reg  [`REG_WIDTH]   mem_mtval_o,
    output reg  [`REG_WIDTH]   mem_mip_o,
    output reg  [`REG_WIDTH]   mem_medeleg_o,
    output reg  [`REG_WIDTH]   mem_mideleg_o,
    output reg  [`REG_WIDTH]   mem_mscratch_o

);

    always@(posedge clk)begin
        if(rst == `RST )begin
            mem_pc_o        <= 0;
            mem_inst_o      <= 0;
            mem_rd_w_ena_o  <= 0;
            mem_rd_w_addr_o <= 0;
            mem_rd_w_data_o <= 0;         
            mem_halt_ena_o  <= 0;
            mem_skip_o      <= 0;
            mem_reg_valid_o <= 0;
        end
        else if(mem_stall_i)begin
            mem_pc_o        <= mem_pc_o;
            mem_inst_o      <= mem_inst_o;
            mem_rd_w_ena_o  <= mem_rd_w_ena_o;
            mem_rd_w_addr_o <= mem_rd_w_addr_o;
            mem_rd_w_data_o <= mem_rd_w_data_o;         
            mem_halt_ena_o  <= mem_halt_ena_o;
            mem_skip_o      <= mem_skip_o;
            mem_reg_valid_o <= mem_reg_valid_o;
        end
        else begin
            mem_pc_o        <= mem_pc_i;
            mem_inst_o      <= mem_inst_i;
            mem_rd_w_ena_o  <= mem_rd_w_ena_i;
            mem_rd_w_addr_o <= mem_rd_w_addr_i;
            mem_rd_w_data_o <= mem_rd_w_data_i;         
            mem_halt_ena_o  <= mem_halt_ena_i;
            mem_skip_o      <= mem_skip_i;
            mem_reg_valid_o <= mem_reg_valid_i;
        end
    end

        always@(posedge clk)begin
        if(rst == `RST )begin
            mem_mstatus_o  <= 0;
            mem_mie_o      <= 0;
            mem_mtvec_o    <= 0;
            mem_mepc_o     <= 0;
            mem_mcause_o   <= 0;
            mem_mtval_o    <= 0;
            mem_mip_o      <= 0;
            mem_medeleg_o  <= 0;
            mem_mideleg_o  <= 0;
            mem_mscratch_o <= 0;
        end
        else if(mem_stall_i)begin
            mem_mstatus_o  <=  mem_mstatus_o ;
            mem_mie_o      <=  mem_mie_o     ;
            mem_mtvec_o    <=  mem_mtvec_o   ;
            mem_mepc_o     <=  mem_mepc_o    ;
            mem_mcause_o   <=  mem_mcause_o  ;
            mem_mtval_o    <=  mem_mtval_o   ;
            mem_mip_o      <=  mem_mip_o     ;
            mem_medeleg_o  <=  mem_medeleg_o ;
            mem_mideleg_o  <=  mem_mideleg_o ;
            mem_mscratch_o <=  mem_mscratch_o;
        end
        else begin
            mem_mstatus_o  <=  mem_mstatus_i ;
            mem_mie_o      <=  mem_mie_i     ;
            mem_mtvec_o    <=  mem_mtvec_i   ;
            mem_mepc_o     <=  mem_mepc_i    ;
            mem_mcause_o   <=  mem_mcause_i  ;
            mem_mtval_o    <=  mem_mtval_i   ;
            mem_mip_o      <=  mem_mip_i     ;
            mem_medeleg_o  <=  mem_medeleg_i ;
            mem_mideleg_o  <=  mem_mideleg_i ;
            mem_mscratch_o <=  mem_mscratch_i;
        end
    end



endmodule